package Map

import (
	"sanguo/cluster"
	codecs "sanguo/codec/cs"
	"sanguo/node/common/transaction"
	"sanguo/node/node_game/module/role"
	"sanguo/node/node_game/user"
	cs_message "sanguo/protocol/cs/message"
	ss_rpc "sanguo/protocol/ss/rpc"
	"sanguo/rpc/move"
	"time"

	"github.com/golang/protobuf/proto"
)

type transactionMove struct {
	transaction.TransactionBase
	user *user.User
	req  *codecs.Message
}

func (this *transactionMove) GetModuleName() string {
	return "Map"
}

func (this *transactionMove) GetReplyMsg() proto.Message {
	return nil
}

func (this *transactionMove) SetExpiredTime(expired time.Time) {
	this.Expired = expired
}

func (this *transactionMove) GetExpiredTime() time.Time {
	return this.Expired
}

func (this *transactionMove) Begin() {
	roleModule := this.user.GetModuleByName("role").(*role.RoleModule)
	r := roleModule.CurrentRole()
	if nil == r || !r.IsRoleModleData() {
		this.user.EndTrans(this)
	} else {
		node_map, err := cluster.Random("map")
		if nil != err {
			this.user.EndTrans(this)
		} else {
			req := this.req.GetData().(*cs_message.MoveToS)
			arg := &ss_rpc.MoveReq{}
			arg.MapType = proto.Int32(r.GetMapID())
			arg.UserID = proto.String(this.user.GetUserID())
			arg.RoleID = proto.Uint64(r.GetID())
			arg.Pos = &ss_rpc.Position{
				X: proto.Int32(req.GetPos().GetX()),
				Y: proto.Int32(req.GetPos().GetY()),
				Z: proto.Int32(req.GetPos().GetZ()),
			}
			arg.Angle = proto.Int32(req.GetAngle())
			move.AsynCall(node_map, arg, transaction.TransTimeoutMs, func(resp *ss_rpc.MoveResp, err error) {
				if !this.user.CheckTrans(this) {
					//trans已经结束
					return
				}
				if nil == err && resp.GetOk() == 1 {
					pos := resp.GetPos()
					r.SetPos(pos.GetX(), pos.GetY(), pos.GetZ())
					r.SetAngle(req.GetAngle())
				}
				this.user.EndTrans(this)
			})
		}
	}
}

func (this *transactionMove) End() {
}

func (this *transactionMove) Timeout() {
	this.user.EndTrans(this)
}

func init() {
	user.RegisterTransFunc(&cs_message.MoveToS{}, func(user *user.User, msg *codecs.Message) transaction.Transaction {
		return &transactionMove{
			user: user,
			req:  msg,
		}
	})
}
